<?php

namespace Manager;

use W3\Util;
use W3\Json;
use W3\Html;
use W3\Validate;

!defined('W3_ROOT_DIR') AND exit;

/**
 * 内容编辑管理基类
 *
 * @author edikud
 * @date 2022/10/22
 * @copyright Copyright (c) 2022 W3 (http://www.mcooo.com)
 * @license GNU General Public License 2.0
 */

class Post extends Contents
{

    /**
     * 插入内容  
     *
     * @access public
     * @param array $values 内容结构数组
     * @return integer
     */
    public function addPost(array $values)
    {
		/** 计算图片数，和非图片文件数 */
        $numArr = $this->widget('Manager\Attach')->findNums('post', 0, $this->auth->uid);
		
		if(!empty($numArr)) { 
		    $values['imagesNum'] = $numArr[0];
			$values['filesNum'] = $numArr[1];
		}

        /** 发布一个新内容 */
        $insertId = $this->addContents($values);
		
        /** 插入分类 */
        $this->setCategories($insertId, 'add', null, $values);

        /** 插入标签 */
        $this->setTags($insertId, 'add', null, $values);

        /** 同步附件 */
		if(!empty($numArr)) { 
		    $this->widget('Manager\Attach')->sync('post', $insertId, $this->auth->uid);
		}

		return $insertId;
    }

    /**
     * 更新内容
     *
     * @access public
     * @param int $cid 内容cid
     * @param array $content 内容结构数组
     * @return integer
     */
    public function updatePost($cid, array $values)
    {
        $post = $this->db
			->select()
		    ->from('table.contents')
			->where('table.contents.cid = ? AND table.contents.type = ?', $cid, 'post')
			->limit(1)
			->fetch();
		
        if (empty($post))
			
			return ;

		/** 计算图片数，和非图片文件数 */
        $numArr = $this->widget('Manager\Attach')->findNums('post', $cid, $this->auth->uid);
		
		if(!empty($numArr)) { 
		    $values['imagesNum'] = $numArr[0];
			$values['filesNum'] = $numArr[1];
		}
		
        /** 更新数据 */
        $updateRows = $this->updateContents($cid, $values);

        /** 插入分类 */
		$this->setCategories($cid, 'edit', $post, $values);

        /** 插入标签 */
		$this->setTags($cid, 'edit', $post, $values);
		
		return $updateRows;
    }

    /**
     * 删除内容
     *
     * @access public
     * @param int $cid 内容cid
     * @return integer
     */
    public function deletePost($cid)
    {
        $deleteRows = false;

        $post = $this->db
			->select()
		    ->from('table.contents')
			->where('table.contents.cid = ? AND table.contents.type = ?', $cid, 'post')
			->limit(1)
			->fetch();
		
        if (empty($post))
			
			return ;

        /** 删除分类 */
        $this->setCategories($cid, 'delete', $post);

        /** 删除标签 */
        $this->setTags($cid, 'delete', $post);
			
		$commentManager = $this->widget('Manager\Comment');
			
        while (1) 
		{
            $arrlist = $this->db
			    ->select('coid')
				->from('table.comments')
			    ->where('table.comments.cid = ?', $cid)
				->limit(1000)
				->get();
				
            if (empty($arrlist)) {
                break;
            }
				
            foreach ($arrlist as $value) 
		    {
		        $commentManager->deleteComment($value['coid']);
		    }
        }		

        /** 删除附件 */
        $this->widget('Manager\Attach')->remove('post', $cid);
			
		/** 删除文章 */
		$deleteRows = $this->deleteContents($cid);

		return $deleteRows;
    }

    /**
     * 设置内容标签
     *
     * @access public
     * @param integer $cid
     * @param string $type
     * @param array|null $old
     * @param array|null $new
     * @return void
     */
    public function setTags(int $cid, string $type, ?array $old = null, ?array $new = null)
    {
        switch ($type) 
		{
            case 'add':
            case 'edit':

			    $insertTags = [];

				if('edit' == $type){
			
		            # 旧标签
					$taglist = Json::decode($old['tagsJson'] ?: '[]' );
					$oldTags = $taglist ? implode(',', Util::arrayColumn($taglist, 'name')) : null;
					
			        if((!array_key_exists('tags', $new) || $new['tags'] == $oldTags) && (!array_key_exists('status', $new) || $new['status'] == $old['status'])){
				        return ;
			        }

					if(isset($new['tags'])){
						
						$newTags = $new['tags'];
						
		                # 状态为publish
		                $visible = 'publish' == $old['status'];
						
						if($visible){
		                    # 删除标签
	                        foreach($taglist as $mid => $value)
		                    {
			                    $deleteRows = $this->db
			                        ->delete('table.relate')
			                        ->where('mid = ? AND cid = ?', $mid, $cid)
				                    ->affected();
			
                                /** 更新内容数 */
		                        $deleteRows && $this->widget('Manager\Tag')->decr( $mid, 'count' );
	                        }
						}
					} elseif(isset($new['status']) && 'publish' == $new['status'] && 'publish' != $old['status']){

						$newTags = $oldTags;
					}

				} else {
					
					$newTags = $new['tags'] ?? '';
					
				}

                $newTags = str_replace('，', ',', $newTags);
				$newTags = array_unique(array_map('trim', explode(',', $newTags)));
				$taglist = [];
				$i=0;
	            foreach($newTags as $name)
			    {
		            if (empty($name) || !Validate::xss($name)) continue;
					
					# 最多支持20个标签
		            if ($i > 20) break;
						
				    $taglist[] = $name;
					++$i;
			    }

		        # 状态为publish才插入关系数据表
		        $visible = isset($new['status']) && 'publish' == $new['status'];
				
			    if($visible){
						
	                foreach($taglist as $name)
			        {
                        $tagdata = $this->db
				            ->select()
		                    ->from('table.metas')
			                ->where('table.metas.type = ? AND table.metas.name = ?', 'tag', $name)
			                ->fetch();

		                if(empty($tagdata)) {
					
                            $mid = $this->widget('Manager\Tag')->addTag(['name'=>$name]);
					        $tag = $this->db
					            ->select('alias')
					            ->from('table.metas')
						        ->where('table.metas.mid = ?', $mid)
						        ->fetch();
				            $alias = $tag['alias'];
		                } else {
					        $mid = $tagdata['mid'];
					        $alias = $tagdata['alias'];
		                }
			            $insertTags[$mid] = ['alias'=>$alias, 'name'=>$name];
	                }	

	                # 写入标签
	                foreach($insertTags as $mid => $value)
		            {
			            $select = $this->db
			                ->select(1)
			                ->from('table.relate')
				            ->where('mid = ? AND cid = ?', $mid, $cid)
				            ->fetch();
				
			            if(!$select) {
				            $insert = $this->db
				                ->insert('table.relate')
				                ->rows(['mid' => $mid, 'cid' => $cid])
					            ->affected();

                            /** 更新内容数 */
		                    $insert && $this->widget('Manager\Category')->incr( $mid, 'count' );
			            }
	                }
			    } else {
						
					$i=0;
	                foreach($taglist as $name)
			        {
			            $insertTags['_' . $i] = ['alias'=>'', 'name'=>$name];
					    ++$i;
	                }
				}

			    $tagsJson = Json::encode($insertTags);
		        $this->updateContents($cid, ['tagsJson' => $tagsJson]);

            break;

            case 'delete':

		            # 状态为publish
		            $visible = 'publish' == $old['status'];
					
					if($visible){
						
		                $taglist = Json::decode($old['tagsJson'] ?: '[]' );
						
		                # 删除标签
	                    foreach($taglist as $mid => $value)
		                {
			                $deleteRows = $this->db
			                   ->delete('table.relate')
			                   ->where('mid = ? AND cid = ?', $mid, $cid)
				               ->affected();
			
                            /** 更新内容数 */
		                    $deleteRows && $this->widget('Manager\Tag')->decr( $mid, 'count' );
	                    }
					}
            break;
        }
    }

    public function getMids($mids = [])
    {
		$categoryList = $this->widget('Category\Rows');
		$lists = [];
        foreach ($mids as $mid)
		{
            # 分类所有上级
			$parentsMids = $categoryList->getParentsMids($mid);
            foreach ($parentsMids as $mid)
			{
				$lists[$mid] = $mid;
            }
		}
		return $lists;
    }

    /**
     * 设置分类
     *
     * @access public
     * @param integer $cid 内容id
     * @param string $mids
     * @param string $newMids 分类id的集合数组
     * @return void
     */
    public function setCategories(int $cid, $type, ?array $old = null, ?array $new = null)
    {
        switch ($type) 
		{
            case 'add':
            case 'edit':
			
		        $categories = $this->widget('Category\Rows')->export();
		        $insertMids = [];
			
				if('edit' == $type){

			        if(($old['mids'] && !array_key_exists('mids', $new) || $old['mids'] && $new['mids'] == $old['mids']) && (!array_key_exists('status', $new) || $new['status'] == $old['status'])){
				        //return ;
			        }

					if(isset($new['mids'])){
						
						$newMids = $new['mids'];
						
		                # 状态为publish
		                $visible = 'publish' == $old['status'];

		                # 删除旧分类
		                if($visible && $old['mids']){
							
			                $listMids = $this->getMids(explode(',', $old['mids']));

                            foreach ($listMids as $mid)
			                {
                                $delete = $this->db->delete('table.relate')
				                    ->where('mid = ? AND cid = ?', $mid, $cid)
					                ->affected();
					
                                # 分类文章数减1
                                $delete && $this->widget('Manager\Category')->decr( $mid, 'count' );
                            }
		                }
						
					} elseif(isset($new['status']) && 'publish' == $new['status'] && 'publish' != $old['status']){

						$newMids = $old['mids'];
					}

				} else {
					
					$newMids = $new['mids'] ?? '';
					
				}
				
				if($newMids){
					
		            # 过滤分类
		            foreach(explode(',', $newMids) as $mid)
			        {
			            isset($categories[$mid]) && $insertMids[$mid] = $mid;
		            }
				}

			    # 默认分类
		        $insertMids = $insertMids ? $insertMids : [current($categories)['mid']];

		        # 状态为publish才插入关系数据表
		        $visible = isset($new['status']) && 'publish' == $new['status'];
		
		        # 插入分类
		        if($visible){
			
			        $listMids = $this->getMids($insertMids);

                    foreach ($listMids as $mid)
			        {
				        $select = $this->db->select(1)
				            ->from('table.relate')
					        ->where('mid = ? AND cid = ?', $mid, $cid)
					        ->fetch();
					
				        if(!$select){
				            $insert = $this->db
					            ->insert('table.relate')
					            ->rows(['mid' => $mid, 'cid' => $cid])
					            ->affected();
						
                            # 分类文章数加1
                            $insert && $this->widget('Manager\Category')->incr( $mid, 'count' );
				        }
                    }
		        }

			    $this->updateContents( $cid, ['mids' => implode(',', $insertMids)] );

            break;
            case 'delete':

		        # 旧分类Mids
		        $oldMids = $old['mids'];
			
		        # 状态为publish
		        $visible = 'publish' == $old['status'];

		        # 删除旧分类
		        if($visible){
			        $listMids = $this->getMids(explode(',', $oldMids));

                    foreach ($listMids as $mid)
			        {
                        $delete = $this->db->delete('table.relate')
				            ->where('mid = ? AND cid = ?', $mid, $cid)
					        ->affected();
					
                        # 分类文章数减1
                        $delete && $this->widget('Manager\Category')->decr( $mid, 'count' );
                    }
		        }

                break;
        }
    }
	
    /**
     * 生成表单
     *
     * @access public
     * @param string $action 表单动作
     * @return Form
     */
    public function form()
    {
        /** 构建表格 */
        $form = Html::form();
		
        /** 主键 */
        $cid = Html::hidden('cid');
        $form->addInput($cid);
		
        /** 标题 */
        $title = Html::text('title')
		    ->label(__('标题'));
        $form->addInput($title);

        /** 网址缩略名 */
        $alias = Html::text('alias')
		    ->label(__('网址缩略名'));
        $form->addInput($alias);

        /** 分类 */
        $options = [];
        $widgetMetas = $this->widget('Category\Rows');
        while ($widgetMetas->next()) {
            $options[$widgetMetas->mid] = str_repeat('&nbsp;&nbsp;&nbsp;&nbsp;', $widgetMetas->level) . $widgetMetas->name;
        }
        $mids = Html::checkbox('mids', $options)
		    ->label(__('分类'))
		    ->description(__('此文章将归档在您选择的分类下.'))
			->style('padding:6px 0;max-height: 600px;width: 100%;overflow: auto;');
		
        $form->addInput($mids);

        /** 文章 */
        $text = Html::textarea('text')
		    ->label(__('文章内容'))
			->style('min-height: 240px;');
        $form->addInput($text);

        /** 文章 */
        $intro = Html::textarea('intro')
		    ->label(__('摘要'))
			->style('min-height: 120px;');
        $form->addInput($intro);
		
        /** 标签 */
        $tags = Html::text('tags')
		    ->label(__('标签'))
		    ->description(__('逗号分隔, 最多支持5个'));
        $form->addInput($tags);
		
		/** 类型 */
		if($this->parameter->type) {
            $type = Html::select('type', $this->parameter->type, 'page')
		        ->label(__('类型'));
            $form->addInput($type);
		}
		
		/** 状态 */
		if($this->parameter->status) {
            $status = Html::select('status', $this->parameter->status, 'publish')
		        ->label(__('状态'));
            $form->addInput($status);
		}
		
        /** 排序 */
        $order = Html::text('order')
		    ->label(__('排序'));
        $form->addInput($order);		
		
		/** 文章图标 */
        $pic = Html::file('pic')
		    ->label(__('文章图标'))
		    ->description('支持外链');
        $form->addInput($pic);

        $allowComment = Html::checkbox('allowComment', ['1'=>'允许评论'], 1)
		    ->only()
		    ->label(__('评论权限'));
        $form->addInput($allowComment);

        /** 提交按钮 */
        $submit = Html::submit();
        $form->set($submit);
		
        if ($this->cid) {
			
		    if(isset($status)) {
                $status->value($this->status);
		    }
			
			$tagNames = $this->tags ? implode(',', Util::arrayColumn($this->tags, 'name')) : '';
			$tags->value($tagNames);
			$intro->value($this->intro);
			$order->value($this->order);
            $title->value($this->title);
            $alias->value($this->alias);
            $mids->value(explode(',', $this->mids));
			$text->value($this->text);
			$allowComment->value($this->allowComment);
            $cid->value($this->cid);
            $pic->value($this->pic);
		    $this->pic && $pic->append('<img style="margin: 5px 0;" class="w3-pic" src="'.$this->icon .'" />');
            $submit->value(__('更新文章'));

        } else {
            $submit->value(__('发布文章'));
        }	

		/** 插件接口 */
        return \do_action('post_form', $this, false, $form);

    }
}

